package com.woniuxy.util;




import com.woniuxy.common.RedisConst;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;

/**
 * JWT工具类
 */
@Component
@Slf4j
public class JwtUtil {
    //密钥
    @Value("${jwt.secret}")
    private String secret;
    //过期时间
    @Value("${jwt.expiration}")
    private long expiration;

    @Autowired
    RedisTemplate redisTemplate;
    /**
     * 创建Token的方法
     */
    public String createToken(Map<String, Object> claims) {
        //1.创建JWT构建器，并且设置基本的参数
        JwtBuilder builder = Jwts.builder()
                .setSubject("book-mall-system")  //主题
                .setExpiration(new Date(System.currentTimeMillis() + expiration))  //过期时间
                .signWith(SignatureAlgorithm.HS256, secret)  //签名
                .compressWith(CompressionCodecs.GZIP);   //指定压缩格式
        //添加多个键和值
        if (claims != null) {
            builder.setClaims(claims);
        }
        //返回字符串
        return builder.compact();
    }
    /**
     * 解析Token
     */
    public Jws<Claims> parseToken(String token) {
        return Jwts.parser()
                .setSigningKey(secret)
                .parseClaimsJws(token);
    }
    /**
     * 判断Token前面是否有Bearer字符串
     *
     * @return 返回一个Token
     */
    public String getToken(String auth) {
        //Token不为空，而且长度大于7，并且以Bearer开头
        if (auth != null && auth.length() > 7 && auth.startsWith("Bearer ")) {
            //从第7个开始取子字符串
            return auth.substring(7);
        }
        return auth;
    }
    /**
     * 获取指定的值
     */
    public String getValue(String token, String key) {
        //对Token进行处理
        token = getToken(token);
        //解析Token，判断Token是否合法
        Jws<Claims> claimsJws = parseToken(token);
        //获取载荷
        Claims claims = claimsJws.getBody();
        //获取指定的值
        return claims.get(key).toString();
    }

    /**
     * 验证JWT是否有效方法
     */
    public boolean validateToken(String token) {
        //直接调用上面的方法进行解析
        try {
            //去掉了Bearer
            token = getToken(token);
            //验证有效性
            parseToken(token);
            //得到Redis中键
            String userId = getValue(token, "userId");
            String key = RedisConst.USER_TOKEN_PREFIX + ":" + userId;
            //获取Redis中Token
            String redisToken = (String) redisTemplate.opsForValue().get(key);


            //比较是否相等
            return redisToken.equals(token);
        } catch (Exception e) {
            log.info("验证Token失败:{}", e.getMessage());
            return false;
        }
    }

    /**
     * 获取IP地址的方法
     */
    public String getRequestIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}